package com.wyg.composite.duck;

import com.wyg.composite.adapter.GooseAdapter;
import com.wyg.composite.factory.AbstractDuckFactory;
import com.wyg.composite.factory.CountingDuckFactory;

/**
 * @description:    模拟鸭子叫
 * @author: WYG
 * @time: 2021/4/10 21:20
 */

public class DuckSimulator {
    public static void main(String[] args) {
        DuckSimulator simulator = new DuckSimulator();

        simulator.simulate();

        AbstractDuckFactory factory = new CountingDuckFactory();
        simulator.simulate(factory);
    }

    /**
     * 通过工厂模式创建对象
     * @param factory
     */
    public void simulate(AbstractDuckFactory factory) {
        Quackable duckCall = factory.createDuckCall();
        Quackable mallardDuck = factory.createMallardDuck();
        Quackable readheadDuck = factory.createReadheadDuck();
        Quackable rubberDuck = factory.createRubberDuck();
        System.out.println("使用抽象工厂创建");
        simulate(duckCall);
        simulate(mallardDuck);
        simulate(readheadDuck);
        simulate(rubberDuck);
    }

    public void simulate() {
        /*
        Quackable mallardDuck = new MallardDuck();
        Quackable readheadDuck = new ReadheadDuck();
        Quackable duckCall = new DuckCall();
        Quackable rubberDuck = new RubberDuck();
        */
        // 装饰鸭子对象，增加计算鸭子叫声次数的行为
        Quackable mallardDuck = new QuackCounter(new MallardDuck());
        Quackable readheadDuck = new QuackCounter(new ReadheadDuck());
        Quackable duckCall = new QuackCounter(new DuckCall());
        Quackable rubberDuck = new QuackCounter(new RubberDuck());
        // 使用适配器模式，对不同的接口进行适配操作，可以让鹅像鸭子一样
        Quackable gooseDuck = new QuackCounter(new GooseAdapter(new Goose()));
        System.out.println("鸭子模拟器");
        simulate(mallardDuck);
        simulate(readheadDuck);
        simulate(duckCall);
        simulate(rubberDuck);
        // 适配器
        simulate(gooseDuck);

        System.out.println("鸭子总共叫了" + QuackCounter.getNumberQuacks() + "次");
    }

    public void simulate(Quackable quackable) {
        quackable.quack();
    }
}
